import pandas as pd
import re

from datatoolsobj.templates.finace_default import FinaceType

def count_validate(data):
    '''获取data列表中，每行有效数据的个数。
    data：要统计有效数据的列表
    返回：表示每行有效数据个数的数组
    '''
    lens = []
    for index,line in data.iterrows():
        count = 0
        for item in line.tolist():
            if item and not pd.isna(item):
                count += 1
        lens.append(count)
    return lens

def strip_row(line):
    '''去除一行数据中末尾无效内容。
    line：要处理的列表行。
    '''
    line.reverse()
    for i,item in enumerate(line):
        if item:
            #item为有效数字
            #当item为string时判断是否包含Unnamed
            if type(item) != str:
                line.reverse()
                return line[:len(line)-i]
            else:
                if item.find('Unnamed')==-1:
                    line.reverse()
                    return line[:len(line)-i]
                else:
                    continue
                    
    return []

class ExcelReader():
    '''此类主要用于实现xlsx文件和xls文件统一读取、sheet信息获取、自动推测列标题。通过减少读取文件次数提高效率。
    '''
    def __init__(self,path):
        self._p = path
        
        self.wb_data = pd.read_excel(path,header=None,sheet_name=None,nrows=10)

    def getSheetNames(self):
        '''获取xls和xlsx文件中指定路径下的工作簿文件中sheet列表。
        sheetlist:当前工作簿中包含的sheet列表。
        '''

        sheetlist = list(self.wb_data.keys())

        return sheetlist
    
    def detectHeader(self,sheetname=None,max_row=10):
        '''自动检测给定路的excel文件中，表标题位置、表列标题名称位置。。
        sheetname:要自动检测的excel表的表名。若为None则表示默认打开第一个表。
        max_row:检测表头部范围，默认在前10行范围内检测
        '''
        if not sheetname:
            sheetname = self.getSheetNames()[0]
        data = self.wb_data[sheetname]

        #此处，需要加入特殊格式的财务文件处理
        # 格式：|  2022年  | 凭证号  | 摘要   | 贷方  |  借/贷  |  余额  |
        #       | 月 | 日 |         |        |       |         |       |
        # 这种格式中，标题行使用通用探测方式会失败，需要提前处理
        # 方案：1.检测【月】【日】单元格，判断是否相邻，然后判断上一行是否符合这种模式
        #       2.一但符合，测试其他列是否可拆分（全合并）
        #       3.将首行年中的合并单元格填充。
        # special_date,coord_date = detectSpecialDateCell(data)
        # if special_date:
        #     data.iloc[coord_date[0],[coord_date[1],coord_date[1]+1]] = ['月','日']
        ft = FinaceType(data)
        ft.unification()
        file_type = ft.getName()

        lens = count_validate(data)
        row_index = 0
        max_items = 0
        for i,item in enumerate(lens):
            if item > max_items:
                row_index = i
                max_items = item

        columns = strip_row(data.loc[row_index,:].tolist())
        
        result_cols = []
        result_cols_index = []
        for i,item in enumerate(columns):
            result_cols_index.append(i)
            if pd.isnull(item):
                result_cols.append('Unname:%d'%i)
            else:
                if type(item) != 'str':
                    item = str(item)
                result_cols.append(re.sub('\s*','',item))               

        data = pd.read_excel(self._p,sheet_name=sheetname,usecols=result_cols_index,header=row_index,nrows=max_row)
        columns_type = []
        for col_index,col_item in enumerate(columns):
            columns_type.append(str(data.iloc[:,col_index].dtype))
                
        table = {
            'columns':{'columns_item':result_cols,'columns_pos':result_cols_index},
            'columns_type':columns_type,
            'columns_index':row_index,
            'file_hdr_type':file_type,
        }
    
        return table